package menu
{
	import com.*;
	import com.Logging.ClientAction;
	import com.Logging.ClientActionType;
	import data.*;
	import events.GCEvent;
	import ui.button.GCButton;
	import ui.list.GCItemScrollList;
	import ui.list.GCListUI;
	import ui.list.ScrollList;
	import ui.popup.GCInventoryPopup;
	import ui.textfield.GCStylizedText;
	
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import org.flixel.FlxG;
	
	
	/**
	 * Shows the inventory at the warehouse of a city. Also
	 * is where the player can transfer goods between city storage and
	 * ship storage.
	 * @author Jason Won
	 */
	public class GCWarehouseMenu extends Sprite implements GCSuperMenu
	{		
		// Inventory lists
		private var _shipInventoryList:GCItemScrollList;
		private var _warehouseInventoryList:GCItemScrollList;
		private var _salesInventoryList:GCItemScrollList;
		
		// UI buttons		
		private var _loadButton:GCButton;
		private var _unloadButton:GCButton;
		private var _exitButton:GCButton;
		
		// Transfer Helpers
		private var _selectedItemUI:GCListUI;
		private var _selectedItem:GCItem;
		
		// Popup dealing with transferring your inventory
		private var _inventoryTransferPopup:GCInventoryPopup;
		
		// Labels
		private var _shipItemsLabel:GCStylizedText;
		private var _warehouseItemsLabel:GCStylizedText;
		
		public function GCWarehouseMenu() 
		{
			// Construct the inventory lists
			_shipInventoryList = new GCItemScrollList(300, 400, true);
			_warehouseInventoryList = new GCItemScrollList(300, 400, true);	
			_salesInventoryList = new GCItemScrollList(300, 400, true);
			
			// Construct the menu buttons
			_loadButton = new GCButton(onLoadClick);
			_unloadButton = new GCButton(onUnloadClick);
			_exitButton = new GCButton(onExitMenu);
			
			// Initialize Helpers
			_selectedItemUI = null;
			_selectedItem = null;
			
			// Create the inventory transfer popup
			_inventoryTransferPopup = new GCInventoryPopup();
			
			// Labels
			_shipItemsLabel = new GCStylizedText();
			_warehouseItemsLabel = new GCStylizedText();
			
			init();
			
			// Background
			this.graphics.beginFill(0xbbbbaa);
			this.graphics.drawRect(0, 0, GCMainDisplay.WIDTH, GCMainDisplay.HEIGHT);
			this.graphics.endFill();
		}
		
		private function init():void
		{
			// Inventory Popup
			_inventoryTransferPopup.addEventListener(GCEvent.LOAD_CONFIRM_EVENT, onLoadConfirm);
			_inventoryTransferPopup.addEventListener(GCEvent.UNLOAD_CONFIRM_EVENT, onUnloadConfirm);
			_inventoryTransferPopup.addEventListener(GCEvent.CANCEL_EVENT, onCancel);
			
			// List
			_shipInventoryList.x = 50;
			_shipInventoryList.y = 30;
			_warehouseInventoryList.x = 400;
			_warehouseInventoryList.y = 30;
			_salesInventoryList.x = 400;
			_salesInventoryList.y = 30;
			this.addChild(_shipInventoryList);
			this.addChild(_warehouseInventoryList);
			
			// UI Buttons
			_loadButton.loadGraphic(GCResources.plate, 150, 30);
			_loadButton.loadText("Load Ship");
			_loadButton.x = 475;
			_loadButton.y = 450;
			
			_unloadButton.loadGraphic(GCResources.plate, 150, 30);
			_unloadButton.loadText("Unload Ship");
			_unloadButton.x = 115;
			_unloadButton.y = 450;
			
			_exitButton.loadGraphic(GCResources.plate, 150, 30);
			_exitButton.loadText("Leave Warehouse");
			_exitButton.x = 600;
			_exitButton.y = 480;
			
			this.addChild(_loadButton);
			this.addChild(_unloadButton);
			this.addChild(_exitButton);
			
			_shipItemsLabel.text = "Items on Ship";
			_shipItemsLabel.x = _shipInventoryList.x;
			_shipItemsLabel.setBgStyle(GCStylizedText.STYLE_ONE, _shipInventoryList.width, 30);
			_warehouseItemsLabel.text = "Items in Warehouse";
			_warehouseItemsLabel.x = _warehouseInventoryList.x;
			_warehouseItemsLabel.setBgStyle(GCStylizedText.STYLE_ONE, _warehouseInventoryList.width, 30);
			
			this.addChild(_shipItemsLabel);
			this.addChild(_warehouseItemsLabel);
		}
		
		/**
		 * At this point we will populate the menus with the items in the player's
		 * ship and the inventory of the player's warehouse
		 */
		public function openMenu(shipInventory:GCInventory, warehouseInventory:GCInventory, salesInventory:GCInventory, warehouseListId:uint):void
		{			
			_loadButton.disable();
			_unloadButton.disable();
			_shipItemsLabel.visible = false;
			
			// Add the items into the inventories
			if (GCPlayState.tutorialSequence.currentTutorialStage > GCTutorial.STAGE_FIRST_ORDER)
			{
				_shipItemsLabel.visible = true;
				_loadButton.enable();
				_unloadButton.enable();
				_shipInventoryList.loadInventory(shipInventory);
			}
			
			if (GCPlayState.tutorialSequence.currentTutorialStage == GCTutorial.STAGE_ON_RETURN)
			{
				/*
				* Roy-- tutorial
				* Before selling anything, prompt the user that they need to unload
				* goods at this menu from ship to warehouse.
				*/
				if (GCPlayState.tutorialSequence.getTutorialQuestFromTemplate(GCQuestData.QUEST_TEMPLATE_TUTORIAL_18) != null)
				{
					GCPlayState.dispatchTutorialComplete(GCQuestData.QUEST_TEMPLATE_TUTORIAL_18);
				}
			}

			if (warehouseListId != GCPlayState.getCurrentCity().getId())
			{
				_loadButton.disable();
				_unloadButton.disable();
			}

			_warehouseInventoryList.loadInventory(warehouseInventory);
			_salesInventoryList.loadInventory(salesInventory);
			
			// Clear selections
			_selectedItemUI = null;
			_selectedItem = null;
		}
		
		/**
		 * Clean up this menu
		 */
		public function closeMenu():void
		{
			// Empty the inventory lists
			_shipInventoryList.removeAll();
			_warehouseInventoryList.removeAll();
			_salesInventoryList.removeAll();
			
			// Close all popups
			if (_inventoryTransferPopup.parent != null)
			{
				onCancel();
			}
		}
		
		//----------------------------------------------------------------------
		//	PUBLIC METHODS
		//----------------------------------------------------------------------
		
		/**
		 * Method to call to refresh any dynamic parts on the menu
		 */
		public function refresh():void
		{
			_shipInventoryList.redraw();
			_warehouseInventoryList.redraw();			
		}
		
		
		//----------------------------------------------------------------------
		//	EVENT HANDLERS
		//----------------------------------------------------------------------
		
		/**
		 * Dispatches an exit event.
		 * @param	event
		 */
		private function onExitMenu(event:MouseEvent):void
		{
			dispatchEvent(new GCEvent(GCEvent.EXIT_MENU_EVENT));
		}
		
		/**
		 * Handles the preperation of loading from the warehouse to the ship
		 * @param	event
		 */	
		private function onLoadClick(event:MouseEvent):void
		{	
			_selectedItemUI = _warehouseInventoryList.selected as GCListUI;
			
			if (_selectedItemUI == null)
			{
				// No item selected, just return and don't open popup
				return;
			}

			_selectedItem = _selectedItemUI.reference;
			
			// Capacity Check
			var quantityLimit:int = Math.min(_selectedItem.quantity, _shipInventoryList.remainingCapacity());
			if (quantityLimit < 0) 
			{
				// TODO Should throw a popup here telling that there is no more room left
				return;
			}
			
			// Open up the transfer popup
			_inventoryTransferPopup.initializePopup(quantityLimit, GCItemData.getNameFromId(_selectedItem.itemId), GCInventoryPopup.ACTION_LOADING_SHIP);
			GCPlayState.disableScreen(_inventoryTransferPopup);
		}
		
		/**
		 * Handles the transfer from the warehouse to the ship after 
		 * loading event has been confirmed
		 * @param	event
		 */
		private function onLoadConfirm(event:Event):void
		{			
			var quantity:int = _inventoryTransferPopup.getQuantity();
			
			//DATABASE CALL- move item from city warehouse to the ship
			if (GCConstants.DEBUG_MODE)
			{
				onPerformMove(0);
			}
			else
			{
				GCUtil.moveItem(_selectedItem.invItemId, GCCityData.CITY_SHIP, quantity, function (code:uint, data:Object):void
				{
					// Only use this if merging will not occur i.e. first check if ship has the
					// item
					var newInvItemId:uint = data["id"];
					
					onPerformMove(newInvItemId);
				});
			}
			
			// Perform the actual move
			function onPerformMove(invItemId:uint):void
			{
				// Remove the item from the warehouse
				_warehouseInventoryList.removeItem(_selectedItem);
				trace("CAPACITIES IN CHECK: " + _selectedItem.quantity + " " + _shipInventoryList.remainingCapacity())
				
				// Check quantity
				if (quantity < _selectedItem.quantity)
				{
					// Not all items transferred; Split the items between the two lists
					var newItem:GCItem = _selectedItem.split(invItemId, quantity);
					
					// Load the new split item to the ship's inventory
					_shipInventoryList.addItem(newItem);
					
					// Add the remaining items back to the warehouse inventory
					_warehouseInventoryList.addItem(_selectedItem);
				}
				else if (quantity == _selectedItem.quantity)
				{
					// All items are being transferred
					_selectedItem.invItemId = invItemId;
					_shipInventoryList.addItem(_selectedItem);
				}

				if (GCConstants.LOGGING_DATA)
				{
					// Log the transaction
					var o:Object = new Object();
					o["itemId"] = _selectedItem.itemId;
					o["qty"] = quantity;
					GCPlayState.logger.LogAction(new ClientAction(ClientActionType.LOAD_SHIP, o));
				}
				
				// Clear selections
				_selectedItemUI = null;
				_selectedItem = null;
			
				// Clean up the popup
				_inventoryTransferPopup.clearPopup();
				GCPlayState.enableScreen();	
			}
		}
		
		/**
		 * Handles the preperation of unloading from the ship to the warehouse
		 * @param	event
		 */
		private function onUnloadClick(event:MouseEvent):void
		{			
			_selectedItemUI = _shipInventoryList.selected as GCListUI;
			
			if (_selectedItemUI == null)
			{
				// No item selected, just return and don't open popup
				return;
			}
			
			_selectedItem = _selectedItemUI.reference;
			// Capacity Check
			var quantityLimit:int = Math.min(_selectedItem.quantity, _warehouseInventoryList.remainingCapacity());
			if (quantityLimit < 0) 
			{
				// TODO Should throw a popup here telling that there is no more room left
				return;
			}
			
			// Open up the item transfer popup
			_inventoryTransferPopup.initializePopup(quantityLimit, GCItemData.getNameFromId(_selectedItem.itemId), GCInventoryPopup.ACTION_UNLOADING_SHIP);
			GCPlayState.disableScreen(_inventoryTransferPopup);
		}	
		
		/**
		 * Handles the transfer from the ship to the warehouse after
		 * unloading event has been confirmed
		 * @param	event
		 */
		private function onUnloadConfirm(event:Event):void
		{
			var quantity:int = _inventoryTransferPopup.getQuantity();	
			
			//DATABASE CALL- move item from ship to warehouse
			if (GCConstants.DEBUG_MODE)
			{
				onPerformUnload(0);
			}
			else
			{
				GCUtil.moveItem(_selectedItem.invItemId, GCPlayState.getCurrentCity().getId(), quantity, function (code:uint, data:Object):void
				{
					// Only use this if merging will not occur i.e. first check if warehouse has the
					// item
					var newInvItemId:uint = data["id"];
					onPerformUnload(newInvItemId);	
				});
			}
				
			function onPerformUnload(invItemId:uint):void
			{
				// Remove the item from the ship
				_shipInventoryList.removeItem(_selectedItem);
				
				// Check quantity
				if (quantity < _selectedItem.quantity)
				{
					// Not all items transferred; Split the items between the two lists
					var newItem:GCItem = _selectedItem.split(invItemId, quantity);
					
					// Load the new split item to the warehouse inventory
					_warehouseInventoryList.addItem(newItem);
					
					// Add the remaining items back to the ship inventory
					_shipInventoryList.addItem(_selectedItem);
				}
				else if (quantity == _selectedItem.quantity)
				{
					// All items are being transferred
					_selectedItem.invItemId = invItemId;
					_warehouseInventoryList.addItem(_selectedItem);
				}

				if (GCConstants.LOGGING_DATA)
				{
					// Log the object being unloaded
					var o:Object = new Object();
					o["itemId"] = _selectedItem.itemId;
					o["qty"] = quantity;
					GCPlayState.logger.LogAction(new ClientAction(ClientActionType.UNLOAD_SHIP, o));
				}
				
				// Clear selections
				_selectedItemUI = null;
				_selectedItem = null;
				
				// Clean up the popup
				_inventoryTransferPopup.clearPopup();
				GCPlayState.enableScreen();
			}
		}
		
		/**
		 * Handles cleaning up the popup after transfer has been canceled
		 * @param	event
		 */		
		private function onCancel(event:Event = null):void
		{
			// No transfer; Clean up the popup
			_inventoryTransferPopup.clearPopup();
			GCPlayState.enableScreen();
		}
	}
}